package com.tanhua.dubbo.api.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.dubbo.api.SoundApi;
import com.tanhua.dubbo.api.UserLikeApi;
import com.tanhua.dubbo.enums.IdType;
import com.tanhua.dubbo.pojo.Sound;
import com.tanhua.dubbo.service.IdService;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@DubboService(version = "1.0.0")
public class SoundApiImpl implements SoundApi {

    @Autowired
    private IdService idService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserLikeApi userLikeApi;

    @Value("${tanhua.default.time}")
    private String time;

    /**
     * 保存语音
     *
     * @param sound
     * @return 保存成功后，返回语音id
     */
    @Override
    public String saveSound(Sound sound) {
        //校验
        if (!ObjectUtil.isAllNotEmpty(sound.getUserId(), sound.getUrl())) {
            return null;
        }

        sound.setId(ObjectId.get());
        sound.setSid(this.idService.createId(IdType.SOUND));
        sound.setCreated(System.currentTimeMillis());

        //将数据存到MongoDB
        this.mongoTemplate.save(sound);
        return sound.getId().toHexString();
    }

    /**
     * 查询语音列表,查询时需要排除喜欢和不喜欢的用户以及自己
     *
     * @param userId
     * @return
     */
    @Scheduled
    @Override
    public List<Sound> querySoundByUserId(Long userId) {
        //排除喜欢和不喜欢列表以及自己
        List<Long> likeList = this.userLikeApi.queryLikeList(userId);
        List<Long> notLikeList = this.userLikeApi.queryNotLikeList(userId);

        List<Long> userIdList = new ArrayList<>();
        CollUtil.addAll(userIdList, likeList);
        CollUtil.addAll(userIdList, notLikeList);
        userIdList.add(userId);

        Query query = Query.query(Criteria.where("userId").nin(userIdList));
        return this.mongoTemplate.find(query, Sound.class);
    }

    /**
     * 获取剩余次数
     *
     * @param userId
     * @return
     */
    @Override
    public Integer getCount(Long userId, String key) {
        String count = this.redisTemplate.opsForValue().get(key + userId);
        if (StrUtil.isEmpty(count)) {
            //获取当前时间到当天结束的剩余秒数
            Integer seconds = this.getRemainSecondsOneDay(new Date());
            this.redisTemplate.opsForValue().set(key + userId, time , seconds, TimeUnit.SECONDS);
            //返回剩余次数
            return Convert.toInt(time);
        }
        if (Convert.toInt(count) <= 0) {
            return 0;
        }
        //自增长-1,返回剩余次数
        return Convert.toInt(this.redisTemplate.opsForValue().increment(key + userId, -1));
    }

    //获取当前时间到当天结束的剩余秒数
    private Integer getRemainSecondsOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault()).plusDays(1).withHour(0).withMinute(0)
                .withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault());
        long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);
        return (int) seconds;
    }


}
